package interrupt;

import org.junit.Test;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * 线程中断机制测试类
 *
 * @author codefish
 * @version 1.0
 * @date 2022/08/05 下午 03:46
 */
public class InterruptTest {
    volatile boolean isStop = false;

    @Test
    public void volatileTest() throws InterruptedException {
        new Thread(() -> {
            while (!isStop) {
                System.out.println("t1 运行-----");
            }
            System.out.println("t1 停止-----");
        }, "t1").start();
        Thread.sleep(10);
        new Thread(() -> {
            System.out.println("t2请求中断t1");
            isStop = true;
        }, "t2").start();
    }

    AtomicBoolean isStopAtomic = new AtomicBoolean(false);

    @Test
    public void atomicTest() throws InterruptedException {
        new Thread(() -> {
            while (!isStopAtomic.get()) {
                System.out.println("t1 运行-----");
            }
            System.out.println("t1 停止-----");
        }, "t1").start();
        Thread.sleep(10);
        new Thread(() -> {
            System.out.println("t2请求中断t1");
            isStopAtomic.set(true);
        }, "t2").start();
    }

    @Test
    public void threadAPITest() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("t1 运行-----");
            }
            System.out.println("t1 停止-----");
        }, "t1");
        t1.start();

        Thread.sleep(10);
        new Thread(() -> {
            System.out.println("t2请求中断t1");
            t1.interrupt();
        }, "t2").start();
    }

    @Test
    public void interruptMoreTest1() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            for (int i = 1; i <= 300; i++) {
                System.out.println(threadTag() + "------:" + i);
            }
            System.out.println(threadTag() + Thread.currentThread().isInterrupted());//true
        }, "t1");
        t1.start();
        Thread.sleep(2);
        t1.interrupt();
        //t1线程仍在运行，调用interrupt时中断位置为true
        System.out.println(threadTag() + t1.isInterrupted());//true
        Thread.sleep(2000);
        //2s后线程t1已经停止，线程终端位无效，此时不管调用多少次interrupt，中断位结果都为false

        // t1.interrupt();
        System.out.println(threadTag() + t1.isInterrupted());//false
    }

    @Test
    public void interruptMoreTest2() throws InterruptedException {
        Thread t1 = new Thread(() -> {
            while (true) {
                System.out.println("------t1------");
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("t1中断");
                    break;
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    //线程阻塞时如果被打断会立刻退出阻塞状态并抛出InterruptedException异常，
                    // 并且会清除中断位(设置为false)，
                    //因此需要在catch里再次调用interrupt来将线程中断位设置为true
                    Thread.currentThread().interrupt();
                    e.printStackTrace();
                }
            }
        }, "t1");
        t1.start();
        Thread.sleep(1000);
        t1.interrupt();
        System.out.println("main线程尝试打断t1");

        //等待t1完成
        t1.join();
    }


    @Test
    public void interruptMoreTest3() throws InterruptedException {


        Thread t1 = new Thread(() -> {
            System.out.println("将中断位设为true");
            //t1自身将中断位设为true
            Thread.currentThread().interrupt();
            //第一次调用静态的interrupted()方法，返回true，并且清除线程中断位
            System.out.println("中断位为" + Thread.interrupted());//true
            //由于线程中断位被清除，返回的都是false
            System.out.println("中断位为" + Thread.interrupted());//false
            System.out.println("中断位为" + Thread.currentThread().isInterrupted());//false
        }, "t1");
        t1.start();

        //等待t1完成
        t1.join();
    }

    private String threadTag() {
        return "[" + Thread.currentThread().getName() + "]";
    }


}
